package org.ooho.lesson01;

import org.ooho.util.DBManager;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * Created by HugHo on 2016/9/19.
 */
public class Register extends HttpServlet {
    private String errMsg = "";

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        response.sendRedirect("./register.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Map<String, String[]> mptmp = request.getParameterMap();

        if(mptmp != null && mptmp.size() > 0){
            boolean rslt = registerCheck(mptmp);
            if(!rslt){
                System.out.println("[REGISTER FAILED] : " + this.errMsg);

//                response.sendRedirect("/register.jsp?errMsg=" + this.errMsg);
                request.setAttribute("errMsg", this.errMsg);
                request.setAttribute("userTmp", mptmp);
                request.getRequestDispatcher("./register.jsp").forward(request, response);
            }else{
                System.out.println("[REGISTER SUCCESS]");
                if(addUser(mptmp)){
                    HttpSession session = request.getSession();
                    session.setAttribute("username", mptmp.get("username")[0]);
                    response.sendRedirect("./welcome.jsp");
                }
            }
        }
    }

    private boolean addUser(Map<String, String[]> mp){
        DBManager dbm = new DBManager("test");
        Connection conn = dbm.getConn();

        StringBuilder sql = new StringBuilder("INSERT INTO users (username, password, sex, age) VALUES (?, ?, ?, ?)");

        boolean rslt = false;
        try(PreparedStatement pstmt = conn.prepareStatement(String.valueOf(sql))) {
            pstmt.setString(1, mp.get("username")[0]);
            pstmt.setString(2, mp.get("password")[0]);
            pstmt.setBoolean(3, Boolean.valueOf(mp.get("sex")[0]));
            pstmt.setInt(4, Integer.valueOf(mp.get("age")[0]));

            rslt = pstmt.executeUpdate() == 1;
        } catch (SQLException e) {
            e.printStackTrace();
        }

        dbm.close();
        return rslt;
    }

    private boolean registerCheck(Map<String, String[]> mp){
        // check null
        for(Map.Entry<String, String[]> entry : mp.entrySet()){
            if(entry.getValue()[0].equals("")){
                this.errMsg = entry.getKey() + " can not be null.";
                return false;
            }
        }

        // custom check ( such as: "password eq re_password" )
        if(!mp.get("password")[0].equals(mp.get("re_password")[0])){
            this.errMsg = "repassword not eq password";
            return false;
        }

        // check invalid
        boolean isUsername = registerRule.isUsername(mp.get("username")[0]);
        boolean isPassword = registerRule.isPassword(mp.get("password")[0]);
        boolean isAge = registerRule.isAge(mp.get("age")[0]);

        if(!isUsername) { this.errMsg = "username invalid"; return false; }
        if(!isPassword) { this.errMsg = "password invalid"; return false; }
        if(!isAge) { this.errMsg = "age invalid"; return false; }

        // check exist
        DBManager dbm = new DBManager("test");
        boolean rslt = dbm.isExist("users", "username", mp.get("username")[0]);

        dbm.close();

        if(rslt){
            this.errMsg = "username already existed";
            return false;
        }

        return true;
    }
}

class registerRule{
    public static final Pattern ACCOUNT = Pattern.compile("^\\w{6,20}$");
    public static final Pattern EMAIL = Pattern.compile("[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])");
    public static final Pattern PASSWORD = Pattern.compile("^[\\w!@#$%^&*+-/]{6,20}$");
    public static final Pattern AGE = Pattern.compile("1\\d{2}|[1-9]\\d|\\d");

    // username rule: email only (for now
    public static boolean isUsername(String str){
        return EMAIL.matcher(str).matches();
    }

    public static boolean isPassword(String str){
        return PASSWORD.matcher(str).matches();
    }

    public static boolean isAge(String str){
        return AGE.matcher(str).matches();
    }
}
